package cn.edu.henu.team.ui;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.SaveListener;
import cn.edu.henu.team.MPChart.barEntry;
import cn.edu.henu.team.R;
import cn.edu.henu.team.base.BaseActivity;
import cn.edu.henu.team.bean._User;
import cn.edu.henu.team.bean.clinic;
import cn.edu.henu.team.bean.clinicAvg;
import cn.edu.henu.team.bean.messageBoard;
import cn.edu.henu.team.table.the_clinic;
import cn.edu.henu.team.utils.LocationUtils;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.maps.model.LatLng;
import com.amap.api.services.geocoder.GeocodeAddress;
import com.amap.api.services.geocoder.GeocodeQuery;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshListener;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.bin.david.form.core.SmartTable;
import com.bin.david.form.core.TableConfig;
import com.bin.david.form.data.CellInfo;
import com.bin.david.form.data.format.bg.BaseCellBackgroundFormat;
import com.bin.david.form.data.style.FontStyle;

public class SortCityActivity extends BaseActivity {
    private String zone = "#";
    private String city;
    private int sortNum = 6;
    private ImageView back;
    private EditText et_search;
    private TextView addressMsg;
    private SmartRefreshLayout refreshSrl;
    private ScrollView scrollView;
    private SmartTable table;
    private BarChart barChart;
    private List<the_clinic> smartData = new ArrayList<the_clinic>();  // 表格数据集
    private List<clinic> mData = new ArrayList<clinic>();          // 接收数据集
    private List<barEntry> barEntries = new ArrayList<barEntry>();   // 柱状图数据集
    private List<clinicAvg> sortData = new ArrayList<clinicAvg>(); // 待排数据集
    private clinicAvg[] mClinicAvgs;
    private Toolbar mToolbar;
    private double lng,lat;
    private String end;
    private AlertDialog msgDialog;
    private String cityName;
    private String cityCode;

    @Override
    protected int initLayout() {
        return R.layout.activity_sort_city;
    }

    @Override
    protected void initView() {
        LocationUtils.start(SortCityActivity.this, new LocationUtils.onLocationListener() {
            @Override
            public void getData(AMapLocation aMapLocation) {
               cityCode = aMapLocation.getCityCode();
            }
        });

        back = findViewById(R.id.back);
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mToolbar = findViewById(R.id.toolbar);
        mToolbar.inflateMenu(R.menu.toolbar_menu_4);
        mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.vote:
                        startActivity(new Intent(SortCityActivity.this, VoteActivity.class));
                        break;
                    case R.id.navicate:
                        final LinearLayout layout=new LinearLayout(mContext);
                        //加载布局
                        View view= LayoutInflater.from(mContext).inflate(R.layout.dialog_cityname,layout,false);
                        final EditText content = view.findViewById(R.id.cityName);

                        //加入视图
                        layout.addView(view);
                        if (msgDialog == null) {
                            msgDialog = new AlertDialog.Builder(SortCityActivity.this)
                                    .setTitle("输入想去的合法地址信息: ")
                                    .setView(layout)
                                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int which) {
                                           cityName = content.getText().toString();
                                           getLatlon(cityName);
                                           gotoGaodeMap(SortCityActivity.this, lat, lng, cityName);
                                        }
                                    })
                                    .setNegativeButton("取消", null)
                                    .create();
                        }
                        if (!msgDialog.isShowing()) {
                            msgDialog.show();
                        }
                        break;
                    default:break;
                }
                return true;
            }
        });

        addressMsg = findViewById(R.id.address);
        _User user = BmobUser.getCurrentUser(_User.class);
        addressMsg.setText(user.getAddressMsg());

        refreshSrl = findViewById(R.id.refresh_srl_book);
        refreshSrl.setRefreshHeader(new ClassicsHeader(getApplicationContext()));
        table = findViewById(R.id.table);

        barChart = findViewById(R.id.BarChart);
        refreshSrl.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                refreshSrl.finishRefresh(1000/*,false*/);
                refreshData(zone);
            }
        });

        scrollView = findViewById(R.id.scroll);
        if (scrollView != null) {
            scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
                @Override
                public void onScrollChanged() {
                }
            });
        }

        et_search = findViewById(R.id.et_search);
        et_search.addTextChangedListener(new TextWatcher() {
            //每次EditText文本改变之前的时候，会回调这个方法
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                //s     输入框中改变前的字符串信息
                //start 输入框中改变前的字符串的起始位置
                //count 输入框中改变前后的字符串改变数量一般为0
                //after 输入框中改变后的字符串与起始位置的偏移量
            }

            //每次EditText文本改变的时候，会回调这个方法
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                //第一个参数s 的含义: 输入框中改变后的字符串信息
                //start 输入框中改变后的字符串的起始位置
                //before 输入框中改变前的字符串的位置 默认为0
                //count 输入框中改变后的一共输入字符串的数量
                zone = s.toString();
                refreshData(zone);
            }

            //每次EditText文本改变之后的时候，会回调这个方法
            @Override
            public void afterTextChanged(Editable s) {
                //edit  输入结束呈现在输入框中的信息
            }
        });
    }

    /**
     * 启动高德App进行导航
     */
    public static void gotoGaodeMap(Context context, double lat, double lng, String end) {
        try {
            LatLng latLng = new LatLng(lat, lng);
            Uri uri = Uri.parse("amapuri://route/plan/?dlat=" + latLng.latitude + "&dlon=" + latLng.longitude + "&dname=" + end + "&dev=0&t=0");
            Intent intent = new Intent("android.intent.action.VIEW", uri);
            intent.addCategory("android.intent.category.DEFAULT");
            context.startActivity(intent);
        } catch (Exception e) {
            Toast.makeText(context,"请安装高德地图",Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void initData() {
        LocationUtils.start(getApplicationContext(), new LocationUtils.onLocationListener() {
            @Override
            public void getData(AMapLocation aMapLocation) {
                city = aMapLocation.getCity();
            }
        });

        BmobQuery<clinic> query = new BmobQuery<clinic>();
        query.addWhereEqualTo("citys", city);
        query.findObjects(new FindListener<clinic>() {
            @Override
            public void done(List<clinic> list, BmobException e) {
                if (e == null) {
                    if (list.size() > 0) {
                        mData = list;
                        mClinicAvgs = new clinicAvg[list.size()];
                        calculateAvg(list);

                        sortNum = Math.min(sortNum,list.size());

                        for (int i = 0; i < sortNum; i++) {
                            clinicAvg c = sortData.get(i);
                            barEntry bar = new barEntry(c.getName(), String.format("%.2f", c.getAvg()));
                            barEntries.add(bar);
                        }

                        BarChartStyle(barEntries);

                        for (int i = 0; i < list.size(); i++) {
                            clinicAvg c = sortData.get(i);
                            the_clinic cp = new the_clinic((i + 1), c.getName(), c.getKinds(), c.getAddress(), c.getPhone(), c.getSum(), String.format("%.2f", c.getAvg()));
                            smartData.add(cp);
                        }

                        table.setData(smartData);
                        table.setZoom(true);
                        table.getConfig().setShowTableTitle(false);
                        table.getConfig().setShowXSequence(false);
                        table.getConfig().setShowYSequence(false);
                        table.getConfig().setMinTableWidth(1024);       //设置表格最小宽度
                        FontStyle style = new FontStyle();
                        style.setTextSize(35);
                        style.setTextColor(Color.BLUE);
                        table.getConfig().setContentStyle(style);       //设置表格主题字体样式
                        table.getConfig().setColumnTitleStyle(style);   //设置表格标题字体样式
                        table.getConfig().setContentCellBackgroundFormat(new BaseCellBackgroundFormat<CellInfo>() {     //设置隔行变色
                            @Override
                            public int getBackGroundColor(CellInfo cellInfo) {
                                if (cellInfo.row % 2 == 1) {
                                    return ContextCompat.getColor(SortCityActivity.this, R.color.tableBackground);
                                } else {
                                    return TableConfig.INVALID_COLOR;
                                }
                            }
                        });
                    }
                } else {
                    Toast.makeText(SortCityActivity.this, "数据查询失败", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    public void refreshData(String zone) {
        mData.clear();
        smartData.clear();
        barEntries.clear();

        if (zone.equals("#")) {
            initData();
        } else {
            BmobQuery<clinic> query = new BmobQuery<clinic>();
            query.addWhereEqualTo("kinds", zone);
            query.findObjects(new FindListener<clinic>() {
                @Override
                public void done(List<clinic> list, BmobException e) {
                    if (e == null) {
                        if (list.size() > 0) {
                            mData = list;

                            mClinicAvgs = new clinicAvg[list.size()];
                            calculateAvg(list);

                            sortNum = Math.min(sortNum,list.size());
                            for (int i = 0; i < sortNum; i++) {
                                clinicAvg c = sortData.get(i);
                                barEntry bar = new barEntry(c.getName(), String.format("%.2f", c.getAvg()));
                                barEntries.add(bar);
                            }

                            BarChartStyle(barEntries);

                            for (int i = 0; i < list.size(); i++) {
                                clinicAvg c = sortData.get(i);
                                the_clinic cp = new the_clinic((i + 1), c.getName(), c.getKinds(), c.getAddress(), c.getPhone(), c.getSum(), String.format("%.2f", c.getAvg()));
                                smartData.add(cp);
                            }

                            table.setData(smartData);
                            table.setZoom(true);
                            table.getConfig().setShowTableTitle(false);
                            table.getConfig().setShowXSequence(false);
                            table.getConfig().setShowYSequence(false);
                            table.getConfig().setMinTableWidth(1024);       //设置表格最小宽度
                            FontStyle style = new FontStyle();
                            style.setTextSize(35);
                            style.setTextColor(Color.BLUE);
                            table.getConfig().setContentStyle(style);       //设置表格主题字体样式
                            table.getConfig().setColumnTitleStyle(style);   //设置表格标题字体样式
                            table.getConfig().setContentCellBackgroundFormat(new BaseCellBackgroundFormat<CellInfo>() {     //设置隔行变色
                                @Override
                                public int getBackGroundColor(CellInfo cellInfo) {
                                    if (cellInfo.row % 2 == 1) {
                                        return ContextCompat.getColor(SortCityActivity.this, R.color.tableBackground);
                                    } else {
                                        return TableConfig.INVALID_COLOR;
                                    }
                                }
                            });
                        }
                    } else {
                        Toast.makeText(SortCityActivity.this, "数据查询失败", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }

    // 计算展示的数据中每家医院的相对得分
    public void calculateAvg(List<clinic> list) {
        double sum = 0;
        for (clinic c : list) {
            sum += (c.getSum() * c.getScore());
        }

        for (int i = 0;i<list.size();i++) {
            clinic c = list.get(i);
            double avg = c.getScore() * c.getSum() * 100 / sum;
            clinicAvg cg = new clinicAvg(c.getName(), avg, c.getKinds(), c.getPhone(), c.getAddress(), c.getSum(), c.getScore());
            mClinicAvgs[i] = cg;
        }

        sortData = Arrays.asList(mClinicAvgs);
        Collections.sort(sortData);

        for(clinicAvg c : sortData){
            Log.d("+++++++", c.getName()+c.getAvg());
        }
    }

    // 柱状图样式
    public void BarChartStyle(List<barEntry> mBar) {
        //隐藏图例
        barChart.getLegend().setEnabled(false);
        barChart.getDescription().setEnabled(false);
        //取消缩放、点击、高亮效果
        barChart.setScaleEnabled(false);
        barChart.setClickable(false);
        barChart.setHighlightPerDragEnabled(false);
        barChart.setHighlightPerTapEnabled(false);
        //获取X轴
        XAxis xAxis = barChart.getXAxis();
        //设置X轴在下方（默认X轴在上方）
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        //给X轴添加标签
        xAxis.setValueFormatter(new IndexAxisValueFormatter(new String[]{mBar.get(0).getName(), mBar.get(1).getName(), mBar.get(2).getName(), mBar.get(3).getName(), mBar.get(4).getName(), mBar.get(5).getName()}));
        //取消X轴网格线
        xAxis.setDrawGridLines(false);
        //获取左边Y轴
        YAxis leftYAxis = barChart.getAxisLeft();
        //取消Y轴网格线
        leftYAxis.setDrawGridLines(false);
        //显示左边Y轴的标签
        leftYAxis.setDrawLabels(true);
        //获取右边Y轴
        YAxis rightYAxis = barChart.getAxisRight();
        //隐藏右边Y轴
        rightYAxis.setEnabled(false);

        //添加数据
        List<BarEntry> entries = new ArrayList<>();
        for (int i = 0; i < sortNum; i++) {
            entries.add(new BarEntry(i, Float.parseFloat(mBar.get(i).getAvg())));
        }

        //数据添加到数据集
        BarDataSet dataSet = new BarDataSet(entries, "none");
        //柱体颜色
        dataSet.setColor(Color.parseColor("#FF6363"));
        //显示数值
        dataSet.setDrawValues(true);
        //数据集赋值给数据对象
        BarData data = new BarData(dataSet);
        barChart.setData(data);
        //设置柱体宽带
        data.setBarWidth(0.3f);
    }

    // 查询指定位置的经纬度
    private void getLatlon(String cityName){
        GeocodeSearch geocodeSearch=new GeocodeSearch(SortCityActivity.this);
        geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
                if (i==1000){  // 查询成功
                    if (geocodeResult!=null && geocodeResult.getGeocodeAddressList()!=null && geocodeResult.getGeocodeAddressList().size()>0){
                        GeocodeAddress geocodeAddress = geocodeResult.getGeocodeAddressList().get(0);
                        lat = geocodeAddress.getLatLonPoint().getLatitude();//纬度
                        lng = geocodeAddress.getLatLonPoint().getLongitude();//经度
                    }else {
                        Toast.makeText(SortCityActivity.this,"地名出错",Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });
        GeocodeQuery geocodeQuery=new GeocodeQuery(cityName.trim(),cityCode);
        geocodeSearch.getFromLocationNameAsyn(geocodeQuery);
    }
}